#!/usr/bin/env node
import {
  cpSync,
  existsSync,
  mkdirSync,
  readdirSync,
  readFileSync,
  rmSync,
  writeFileSync
} from 'fs';
import { join } from 'path';
import prompts from 'prompts';

const owoPath = join(process.cwd(), 'emoji');

interface owoOptions {
  [key: string]: {
    type: 'image' | 'emoticon' | 'emoji';
    container: Array<{
      icon: string;
      text: string;
    }>;
  };
}

async function run() {
  let result: prompts.Answers<'ready' | 'isOK' | 'flies' | 'account'>;
  try {
    result = await prompts(
      [
        {
          type: 'confirm',
          name: 'ready',
          message: '开始前请先点击一遍qq表情分类',
          initial: false
        },
        {
          type: (_, { ready }: { ready?: boolean }) => {
            if (ready === false) {
              throw new Error('✖ 操作被取消');
            }
            return null;
          },
          name: 'isOK'
        },
        {
          type: 'text',
          name: 'flies',
          message: '请输入QQ9聊天记录保存位置',
          validate: value => {
            if (!existsSync(value)) {
              return '路径不存在';
            }

            if (!existsSync(join(value, 'nt_qq'))) {
              return '没有找到nt_qq文件夹,请确认是否是QQ9聊天记录文件夹';
            }

            return true;
          }
        },
        {
          type: 'select',
          name: 'account',
          message: '请选择要转换的账号',
          choices: (prev, values, prompt) => {
            const list = readdirSync(values.flies);

            // 只要文件夹
            const dirList = list.filter(item => {
              return existsSync(join(values.flies, item, 'nt_qq'));
            });

            return dirList.map(item => {
              return {
                title: item,
                value: item
              };
            });
          }
        }
      ],
      {
        onCancel: () => {
          throw new Error('✖ 操作被取消');
        }
      }
    );
  } catch (error: any) {
    console.log(error.message);
    return;
  }

  // 表情包文件夹
  const EmojiPath = join(result.flies, result.account, 'nt_qq', 'nt_data', 'Emoji', 'marketface');

  if (!existsSync(EmojiPath)) {
    console.log('没有找到表情包文件夹:', EmojiPath);
    return;
  }
  if (!existsSync(join(EmojiPath, 'json'))) {
    console.log('没有找到表情包json文件夹:', join(EmojiPath, 'json'));
    return;
  }

  console.log('表情包文件夹', EmojiPath);
  console.log('删除表情请删除表情包文件夹下所有文件再重新点击');

  const jsonList = readdirSync(join(EmojiPath, 'json')).filter(item => item.endsWith('.jtmp'));

  if (jsonList.length === 0) {
    console.log('没有找到表情包json文件,请先点击一遍QQ表情分类');
    return;
  }

  console.log('开始转换');

  rmSync(owoPath, { recursive: true, force: true });
  mkdirSync(owoPath);
  await Promise.all(
    jsonList.map(async jsonFile => {
      const json = JSON.parse(readFileSync(join(EmojiPath, 'json', jsonFile), 'utf-8'));
      console.log('开始转换:', json.name);
      mkdirSync(join(owoPath, json.id));
      let owo: owoOptions = {};
      if (json.imgs) {
        owo[json.name] = {} as any;
        owo[json.name].type = 'image';
        owo[json.name].container = json.imgs.map((item: { id: string; name: string }) => {
          if (existsSync(join(EmojiPath, json.id, `${item.id}_thu.png`))) {
            cpSync(
              join(EmojiPath, json.id, `${item.id}_thu.png`),
              join(owoPath, json.id, `${item.id}_thu.png`),
              {
                recursive: true,
                force: true
              }
            );
            return {
              icon: `<img src="/emoji/${json.id}/${item.id}_thu.png">`,
              text: `[${json.name}-${item.name}]`
            };
          } else if (existsSync(join(EmojiPath, json.id, `${item.id}_aio.png`))) {
            cpSync(
              join(EmojiPath, json.id, `${item.id}_aio.png`),
              join(owoPath, json.id, `${item.id}_aio.png`),
              {
                recursive: true,
                force: true
              }
            );
            return {
              icon: `<img src="/emoji/${json.id}/${item.id}_aio.png">`,
              text: `[${json.name}-${item.name}]`
            };
          } else if (existsSync(join(EmojiPath, json.id, `${item.id}.png`))) {
            cpSync(
              join(EmojiPath, json.id, `${item.id}.png`),
              join(owoPath, json.id, `${item.id}.png`),
              {
                recursive: true,
                force: true
              }
            );
            return {
              icon: `<img src="/emoji/${json.id}/${item.id}.png">`,
              text: `[${json.name}-${item.name}]`
            };
          } else {
            return false;
          }
        });
        owo[json.name].container = owo[json.name].container.filter(item => item);
      }
      writeFileSync(join(owoPath, json.id + '.json'), JSON.stringify(owo));
      console.log('转换', json.name, '完成');
    })
  );

  // 合并json文件
  console.log('开始合并json文件');
  const owoList = readdirSync(owoPath).filter(item => item.endsWith('.json'));
  let owo: owoOptions = {};
  await Promise.all(
    owoList.map(async jsonFile => {
      const json: owoOptions = JSON.parse(readFileSync(join(owoPath, jsonFile), 'utf-8'));
      Object.assign(owo, json);
      // 删除json文件
      rmSync(join(owoPath, jsonFile));
    })
  );

  // 给key 排序
  Object.keys(owo)
    .sort()
    .forEach(key => {
      const value = owo[key];
      delete owo[key];
      owo[key] = value;
    });

  writeFileSync(join(owoPath, 'owo.json'), JSON.stringify(owo, null, 2));
  console.log('转换完成');
}

run();
